home *** CD-ROM | disk | FTP | other *** search
/ Network Supervisor's Toolkit / Network Supervisor's Toolkit.iso / tools / nwtp06 / nwmisc.pas < prev    next >
Pascal/Delphi Source File  |  1996-07-10  |  32KB  |  962 lines

  1. {$X+,B-,V-,R-,S-}    { essential compiler directives }
  2.  
  3. UNIT NWMISC;
  4.  
  5. { nwMisc unit as of 950301 / NwTP 0.6 API. (c) 1993,1995 R.Spronk      }
  6. { Includes a bugfix of the EncryptPassword function by Horst Jelonneck }
  7.  
  8. INTERFACE
  9.  
  10. uses nwIntr;
  11.  
  12. { Miscellaneous Functions:            Comments:
  13.  
  14.   Diagnostic Functions:
  15.  
  16. * IsV3Supported
  17. * GetNWversion
  18.  
  19.   Novell types comparison functions:
  20.  
  21. * IsLowerNetworkAddress
  22. * IsEqualNetworkAddress
  23. * IsLaterNovTime
  24. * IsEqualNovTime
  25.  
  26.   Password Encryption Functions:
  27.  
  28. * EncryptPassword                    (1)
  29. * EncryptPasswordDifference          (1)
  30.  
  31.   Conversion Functions:
  32.  
  33. * UpString                           (2)
  34. * HexStr
  35. * HexDumpStr
  36. * PStrCopy
  37. * ZStrCopy
  38. * LoNibble
  39. * HiNibble
  40. * Lswap
  41. * HiLong
  42. * LowLong
  43. * MakeLong
  44. * NovTime2String
  45. * DosTime2NovTime
  46. * NovTime2DosTime
  47. * NovPath2DosPath
  48.   DosPath2NovPath
  49. . MapV2RightsToV3
  50. . MapV3RightsToV2
  51.  
  52. Notes: (1)-Encrypt3 and associated tables adapted from a c source
  53.            (NVPW.C) by Willem Jan Hengeveld, A.K.A. Itsme@Hacktic.nl
  54.           -Source of the encryption routine: LOGON.PAS by Barry Nance,
  55.            [1:141/209] BYTE March'93
  56.        (2) Fast upcasestring by Bob Swart.
  57. }
  58.  
  59.  
  60. Type TnovTime=record
  61.               year,month,day,hour,min,sec,DayOfWeek:byte; { 0=sunday }
  62.               end;
  63.      TconnectionList=array[1..250] of byte;
  64.  
  65.      TencryptionKey=array[0..7] of byte;
  66.      TencrPWdifference=array[0..15] of byte;
  67.  
  68.  
  69.      TnetworkAddress=array[1..4] of byte; { hi-endian }
  70.      TnodeAddress   =array[1..6] of byte; { Hi-endian }
  71.      TinterNetworkAddress=record
  72.                           net   :TnetworkAddress; {hi-lo}
  73.                           node  :Tnodeaddress;    {hi-lo}
  74.                           socket:word;            {lo-hi}
  75.                           end;
  76.  
  77. Function IsV3Supported:Boolean;
  78.  
  79. Procedure NovTime2String(tim:TnovTime;Var DateStr:string);
  80. { Puts the time/date information of a NovTime into a string.
  81.   output format: 'DOW, dd mmm yyyy hh:mm:ss' DOW= day of the week. }
  82.  
  83. Procedure DosTime2NovTime(dt:Longint;Var nt:TnovTime);
  84. { Converts a compact DOS time record (4 bytes) into a Tnovtime record }
  85.  
  86. Procedure NovTime2DosTime(nt:TnovTime;Var dt:Longint);
  87.  
  88. Procedure NovPath2DosPath(np:String;Var dp:string);
  89. { Converts Novell type path into a DOS path of type
  90.   Subdir1\Subdir2\.. \subDirN }
  91.  
  92. {============================level 0 support functions=======================}
  93.  
  94. Procedure UpString(s:string);
  95. { Converts s to upperstring.  Assembler, so it's realy a Var parameter.   }
  96.  
  97. Function HexStr(dw:LongInt;len:byte):string;
  98. { Converts dw into a hex-string of length len.                            }
  99.  
  100. Function HexDumpStr(Var dumpVar;len:Byte):String;
  101. { Converts dumpVar into a hex-string of length len.
  102.   Basically the same as HexStr, but accepts variables only.
  103.   (Mostly used to dump an array of byte)                                  }
  104.  
  105. procedure PStrCopy(Var dest:String;source:String;len:byte);
  106. { if length(source)>len
  107.    then Copy len bytes from source to dest.
  108.    else Copy source to dest and fill out with NULLs.
  109.   Length(Dest) will allways be set to len.                                }
  110.  
  111. procedure ZStrCopy(dest:String;VAR source;len:byte);
  112. { 1. Copies len bytes form an array to a pascal type string.              }
  113. { 2. Trailing NULLs are removed from the string.                          }
  114. { consequently, the length of dest (dest[0]) will allways be <= len.      }
  115. { -SOURCE is an array of byte: array[ ] of byte; }
  116.  
  117. Function IsLowerNetworkAddress(Var a, b): Boolean;
  118. { Compare two net&node addresses.
  119.   a and b should be of type TinternetworkAddress }
  120.  
  121. Function IsEqualNetworkAddress(Var a, b): Boolean;
  122. { Compare two net&node addresses.
  123.   a and b should be of type TinternetworkAddress }
  124.  
  125. Function IsLaterNovTime(time1,time2:TnovTime):boolean;
  126.  
  127. Function IsEqualNovTime(time1,time2:TnovTime):boolean;
  128.  
  129. Function MapV2RightsToV3(V2Rights:byte):word;
  130.  
  131. Function MapV3RightsToV2(V3Rights:Word):Byte;
  132.  
  133. Procedure GetNWversion(Var version:word);
  134. { determine the version of software installed on the current file server. }
  135. { see GetFileServerInformation F217/11 for more information               }
  136. { Version: MajorVersion * 100 + MinorVersion; e.g. 311 for 3.11           }
  137.  
  138. Procedure EncryptPassword(objId:longint;password:string;
  139.                     {i/o} Var Ekey:TencryptionKey);
  140. { called by LoginToFileServer (unit nwConn),
  141.   and by VerifyBinderyObjectPassword, ChangeBinderyObjectPassword (nwBindry) }
  142. { Source of the encryption routine: LOGON.PAS by Barry Nance, [1:141/209]
  143.   BYTE March'93 }
  144.  
  145.  
  146. Procedure EncryptPasswordDifference(objId:Longint;
  147.                                     OldPassword,NewPassword:string;
  148.                                     Var key:TencryptionKey;
  149.                                     Var PWdif:TencrPWdifference;
  150.                                     Var PWdifChecksum:byte
  151.                                     );
  152.  
  153.  
  154. Function LoNibble(b:Byte):Byte;
  155. { Returns the low nibble of the argument (in low nibble position),
  156.   with high nibble set to 0000                                      }
  157. Function HiNibble(b:Byte):Byte;
  158. { Returns the high nibble of the argument (in low nibble position),
  159.   with high nibble set to 0000                                      }
  160.  
  161.  
  162. Function Lswap(l:Longint):Longint;
  163. { swaps bytes in a longInt; ( reverse byte order )                  }
  164. Inline(
  165.   $5A/        {pop DX       ; low word of long                      }
  166.   $58/        {pop AX       ; hi word of long                       }
  167.  
  168.   $86/$F2/    {xchg dl,dh   ; swap bytes                            }
  169.   $86/$E0);   {xchg al,ah   ; swap bytes                            }
  170.  
  171. function HiLong(Long : LongInt) : Word;
  172. { This inline directive is similar to Turbo's Hi() function, except }
  173. { it returns the high word of a LongInt                             }
  174. Inline(
  175.   $5A/       {pop      dx    ; low word of long                     }
  176.   $58);      {pop      ax    ; hi word of long                      }
  177.  
  178. function LowLong(Long : LongInt) : Word;
  179. { This inline directive is similar to Turbo's Lo() function, except }
  180. { it returns the Low word of a LongInt                              }
  181. Inline(
  182.   $5A/       {pop      dx    ; low word of long                     }
  183.   $58/       {pop      ax    ; hi word of long                      }
  184.   $89/$D0);  {mov      ax,dx ; return lo word as func. result in Ax }
  185.  
  186. function MakeLong(HiWord,LoWord : Word) : LongInt;
  187. { Takes hi and lo words and makes a longint                         }
  188. Inline(
  189.   $58/    { pop ax ; pop low word into AX                           }
  190.   $5A);   { pop dx ; pop high word into DX                          }
  191.  
  192.  
  193. CONST
  194. {** ERRORS DEFINED BY NWxxx UNITS *******}
  195.  
  196. {** STANDARD ERRORS AS USED BY NETWARE **}
  197.    HARDWARE_FAILURE                = 255;
  198.    INVALID_INITIAL_SEMAPHORE_VALUE = 255; {nwSema}
  199.    INVALID_SEMAPHORE_HANDLE        = 255; {nwSema}
  200.    BAD_PRINTER_ERROR               = 255;
  201.    QUEUE_FULL_ERROR                = 255;
  202.    NO_FILES_FOUND_ERROR            = 255;
  203.    BAD_RECORD_OFFSET               = 255;
  204.    PATH_NOT_LOCATABLE              = 255;
  205.    SOCKET_ALREADY_OPEN             = 255;
  206.    INVALID_DRIVE_NUMBER            = 255; {nwDir}
  207.    NO_RECORD_FOUND                 = 255;
  208.    NO_RESPONSE_FROM_SERVER         = 255;
  209.    REQUEST_NOT_OUTSTANDING         = 255;
  210.    NO_SUCH_OBJECT_OR_BAD_PASSWORD  = 255;
  211.    CLOSE_FCB_ERROR                 = 255;
  212.    FILE_EXTENSION_ERROR            = 255;
  213.    FILE_NAME_ERROR                 = 255;
  214.    IO_BOUND_ERROR                  = 255;
  215.    SPX_IS_INSTALLED                = 255; {nwIpx}
  216.    SPX_SOCKET_NOT_OPENED           = 255; {nwIpx}
  217.    EXPLICIT_TRANSACTION_ACTIVE     = 255; {nwTTS}
  218.    NO_EXPLICIT_TRANSACTION_ACTIVE  = 255; {nwTTS}
  219.    TRANSACTION_NOT_YET_WRITTEN     = 255; {nwTTS}
  220.    NO_MORE_MATCHING_FILES          = 255; {nwTTS}
  221.    BINDERY_FAILURE                 = 255;
  222.    OPEN_FILES                      = 255;  {3.x}
  223.    PRINT_JOB_ALREADY_QUEUED        = 255;  {3.x}
  224.    PRINT_JOB_ALREADY_SET           = 255;  {3.x}
  225.    SUPERVISOR_HAS_DISABLED_LOGIN   = 254; {nwConn}
  226.    TIMEOUT_FAILURE                 = 254;
  227.    BINDERY_LOCKED                  = 254; {nwBindry}
  228.    SERVER_BINDERY_LOCKED           = 254;
  229.    INVALID_SEMAPHORE_NAME_LENGTH   = 254; {nwSema}
  230.    PACKET_NOT_DELIVERABLE          = 254;
  231.    SOCKET_TABLE_FULL               = 254;
  232.    DIRECTORY_LOCKED                = 254;
  233.    SPOOL_DIRECTORY_ERROR           = 254;
  234.    IMPLICIT_TRANSACTION_ACTIVE     = 254; {nwTTS}
  235.    TRANSACTION_ENDS_RECORD_LOCK    = 254; {nwTTS}
  236.    IO_FAILURE                      = 254;  {3.x}
  237.    UNKNOWN_REQUEST                 = 253;
  238.    INVALID_PACKET_LENGTH           = 253;
  239.    FIELD_ALREADY_LOCKED            = 253;
  240.    BAD_STATION_NUMBER              = 253;
  241.    SPX_MALFORMED_PACKET            = 253;
  242.    SPX_PACKET_OVERFLOW             = 253;
  243.    TTS_DISABLED                    = 253;
  244.    NO_SUCH_OBJECT                  = 252;
  245.    UNKNOWN_FILE_SERVER             = 252;
  246.    INTERNET_PACKET_REQT_CANCELED   = 252;
  247.    MESSAGE_QUEUE_FULL              = 252; {nwMess}
  248.    SPX_LISTEN_CANCELED             = 252;
  249.    NO_SUCH_PROPERTY                = 251;
  250.    INVALID_PARAMETERS              = 251;
  251.    {UNKNOWN_REQUEST                 = 251; ?double see 253}
  252.    NO_MORE_SERVER_SLOTS            = 250;
  253.    TEMP_REMAP_ERROR                = 250;
  254.    NO_PROPERTY_READ_PRIVILEGE      = 249;
  255.    NO_FREE_CONNECTION_SLOTS        = 249;
  256.    NO_PROPERTY_WRITE_PRIVILEGE     = 248;
  257.    ALREADY_ATTACHED_TO_SERVER      = 248;
  258.    NOT_ATTACHED_TO_SERVER          = 248;
  259.    NO_PROPERTY_CREATE_PRIVILEGE    = 247;
  260.    TARGET_DRIVE_NOT_LOCAL          = 247;
  261.    NO_PROPERTY_DELETE_PRIVILEGE    = 246;
  262.    NOT_SAME_LOCAL_DRIVE            = 246;
  263.    NO_OBJECT_CREATE_PRIVILEGE      = 245;
  264.    NO_OBJECT_DELETE_PRIVILEGE      = 244;
  265.    NO_OBJECT_RENAME_PRIVILEGE      = 243;
  266.    NO_OBJECT_READ_PRIVILEGE        = 242;
  267.    INVALID_BINDERY_SECURITY        = 241;
  268.    WILD_CARD_NOT_ALLOWED           = 240;
  269.    IPX_NOT_INSTALLED               = 240; {nwIpx}
  270.    INVALID_NAME                    = 239;
  271.    SPX_CONNECTION_TABLE_FULL       = 239;
  272.    OBJECT_ALREADY_EXISTS           = 238;
  273.    SPX_INVALID_CONNECTION          = 238;
  274.    PROPERTY_ALREADY_EXISTS         = 237;
  275.    SPX_NO_ANSWER_FROM_TARGET       = 237;
  276.    SPX_CONNECTION_FAILED           = 237;
  277.    SPX_CONNECTION_TERMINATED       = 237;
  278.    NO_SUCH_SEGMENT                 = 236;
  279.    SPX_TERMINATED_POORLY           = 236;
  280.    NOT_GROUP_PROPERTY              = 235;
  281.    NO_SUCH_MEMBER                  = 234;
  282.    MEMBER_ALREADY_EXISTS           = 233;
  283.    NOT_ITEM_PROPERTY               = 232;
  284.    WRITE_PROPERTY_TO_GROUP         = 232;
  285.    PASSWORD_HAS_EXPIRED            = 223;
  286.    PASSWORD_HAS_EXPIRED_NO_GRACE   = 222;
  287.    ACCOUNT_DISABLED                = 220;
  288.    UNAUTHORIZED_LOGIN_STATION      = 219;
  289.    MAX_Q_SERVERS                   = 219;
  290.    UNAUTHORIZED_LOGIN_TIME         = 218;
  291.    Q_HALTED                        = 218;
  292.    LOGIN_DENIED_NO_CONNECTION      = 217;
  293.    STN_NOT_SERVER                  = 217;
  294.    PASSWORD_TOO_SHORT              = 216;
  295.    Q_NOT_ACTIVE                    = 216;
  296.    PASSWORD_NOT_UNIQUE             = 215;
  297.    Q_SERVICING                     = 215;
  298.    NO_JOB_RIGHTS                   = 214;
  299.    NO_Q_JOB                        = 213;
  300.    Q_FULL                          = 212;
  301.    NO_Q_RIGHTS                     = 211;
  302.    NO_Q_SERVER                     = 210;
  303.    NO_QUEUE                        = 209;
  304.    Q_ERROR                         = 208;
  305.    NOT_CONSOLE_OPERATOR            = 198;
  306.    INTRUDER_DETECTION_LOCK         = 197;
  307.    ACCOUNT_TOO_MANY_HOLDS          = 195;
  308.    CREDIT_LIMIT_EXCEEDED           = 194;
  309.    NO_ACCOUNT_BALANCE              = 193;
  310.    NO_ACCOUNT_PRIVILEGES           = 192;
  311.    READ_FILE_WITH_RECORD_LOCKED    = 162;
  312.    DIRECTORY_IO_ERROR              = 161;
  313.    DIRECTORY_NOT_EMPTY             = 160;
  314.    DIRECTORY_ACTIVE                = 159;
  315.    INVALID_FILENAME                = 158;
  316.    NO_MORE_DIRECTORY_HANDLES       = 157;
  317.    NO_MORE_TRUSTEES                = 156;
  318.    INVALID_PATH                    = 156;
  319.    BAD_DIRECTORY_HANDLE            = 155;
  320.    RENAMING_ACROSS_VOLUMES         = 154;
  321.    DIRECTORY_FULL                  = 153;
  322.    VOLUME_DOES_NOT_EXIST           = 152;
  323.    NO_DISK_SPACE_FOR_SPOOL_FILE    = 151;
  324.    SERVER_OUT_OF_MEMORY            = 150;
  325.    OUT_OF_DYNAMIC_WORKSPACE        = 150;
  326.    FILE_DETACHED                   = 149;
  327.    NO_WRITE_PRIVILEGES             = 148;
  328.    READ_ONLY                       = 148;
  329.    NO_READ_PRIVILEGES              = 147;
  330.    NO_FILES_RENAMED_NAME_EXISTS    = 146;
  331.    SOME_FILES_RENAMED_NAME_EXISTS  = 145;
  332.    NO_FILES_AFFECTED_READ_ONLY     = 144;
  333.    SOME_FILES_AFFECTED_READ_ONLY   = 143;
  334.    NO_FILES_AFFECTED_IN_USE        = 142;
  335.    SOME_FILES_AFFECTED_IN_USE      = 141;
  336.    NO_MODIFY_PRIVILEGES            = 140;
  337.    NO_RENAME_PRIVILEGES            = 139;
  338.    NO_DELETE_PRIVILEGES            = 138;
  339.    NO_SEARCH_PRIVILEGES            = 137;
  340.    INVALID_FILE_HANDLE             = 136;
  341.    WILD_CARDS_IN_CREATE_FILENAME   = 135;
  342.    CREATE_FILE_EXISTS_READ_ONLY    = 134;
  343.    NO_CREATE_DELETE_PRIVILEGES     = 133;
  344.    NO_CREATE_PRIVILEGES            = 132;
  345.    IO_ERROR_NETWORK_DISK           = 131;
  346.    NO_OPEN_PRIVILEGES              = 130;
  347.    NO_MORE_FILE_HANDLES            = 129;
  348.    FILE_IN_USE_ERROR               = 128;
  349.    DOS_LOCK_VIOLATION              = 33;
  350.    DOS_SHARING_VIOLATION           = 32;
  351.    DOS_NO_MORE_FILES               = 31;
  352.    DOS_NOT_SAME_DEVICE             = 30;
  353.    DOS_ATTEMPT_TO_DEL_CURRENT_DIR  = 16;
  354.    DOS_INVALID_DRIVE               = 15;
  355.    DOS_INVALID_DATA                = 13;
  356.    DOS_INVALID_ACCESS_CODE         = 12;
  357.    DOS_INVALID_FORMAT              = 11;
  358.    DOS_INVALID_ENVIRONMENT         = 10;
  359.    DOS_INVALID_MEMORY_BLOCK_ADDR   = 9;
  360.    DOS_INSUFFICIENT_MEMORY         = 8;
  361.    DOS_MEMORY_BLOCKS_DESTROYED     = 7;
  362.    DOS_INVALID_FILE_HANDLE         = 6;
  363.    DOS_ACCESS_DENIED               = 5;
  364.    DOS_TOO_MANY_OPEN_FILES         = 4;
  365.    DOS_PATH_NOT_FOUND              = 3;
  366.    DOS_FILE_NOT_FOUND              = 2;
  367.    TTS_AVAILABLE                   = 1;
  368.    SERVER_IN_USE                   = 1;
  369.    SEMAPHORE_OVERFLOW              = 1;
  370.    DOS_INVALID_FUNCTION_NUMBER     = 1;
  371.    TTS_NOT_AVAILABLE               = 1;
  372.    SERVER_NOT_IN_USE               = 1;
  373.  
  374. IMPLEMENTATION{=============================================================}
  375.  
  376.  
  377.  
  378. {----------------------- Encryption tables and procedures --------------}
  379.  
  380. TYPE
  381.   Buf32 = ARRAY [0..31] OF Byte;
  382.   Buf16 = ARRAY [0..15] OF Byte;
  383.   Buf8  = ARRAY [0..7]  OF Byte;
  384.   Buf4  = ARRAY [0..3]  OF Byte;
  385.  
  386.  
  387. CONST
  388.   EncryptTable : ARRAY [0..255] OF Byte =
  389. ($7,$8,$0,$8,$6,$4,$E,$4,$5,$C,$1,$7,$B,$F,$A,$8,
  390.  $F,$8,$C,$C,$9,$4,$1,$E,$4,$6,$2,$4,$0,$A,$B,$9,
  391.  $2,$F,$B,$1,$D,$2,$1,$9,$5,$E,$7,$0,$0,$2,$6,$6,
  392.  $0,$7,$3,$8,$2,$9,$3,$F,$7,$F,$C,$F,$6,$4,$A,$0,
  393.  $2,$3,$A,$B,$D,$8,$3,$A,$1,$7,$C,$F,$1,$8,$9,$D,
  394.  $9,$1,$9,$4,$E,$4,$C,$5,$5,$C,$8,$B,$2,$3,$9,$E,
  395.  $7,$7,$6,$9,$E,$F,$C,$8,$D,$1,$A,$6,$E,$D,$0,$7,
  396.  $7,$A,$0,$1,$F,$5,$4,$B,$7,$B,$E,$C,$9,$5,$D,$1,
  397.  $B,$D,$1,$3,$5,$D,$E,$6,$3,$0,$B,$B,$F,$3,$6,$4,
  398.  $9,$D,$A,$3,$1,$4,$9,$4,$8,$3,$B,$E,$5,$0,$5,$2,
  399.  $C,$B,$D,$5,$D,$5,$D,$2,$D,$9,$A,$C,$A,$0,$B,$3,
  400.  $5,$3,$6,$9,$5,$1,$E,$E,$0,$E,$8,$2,$D,$2,$2,$0,
  401.  $4,$F,$8,$5,$9,$6,$8,$6,$B,$A,$B,$F,$0,$7,$2,$8,
  402.  $C,$7,$3,$A,$1,$4,$2,$5,$F,$7,$A,$C,$E,$5,$9,$3,
  403.  $E,$7,$1,$2,$E,$1,$F,$4,$A,$6,$C,$6,$F,$4,$3,$0,
  404.  $C,$0,$3,$6,$F,$8,$7,$B,$2,$D,$C,$6,$A,$A,$8,$D);
  405.  
  406.   EncryptKeys : Array[0..31] of byte =
  407. ($48,$93,$46,$67,$98,$3D,$E6,$8D,$B7,$10,$7A,$26,$5A,$B9,$B1,$35,
  408.  $6B,$0F,$D5,$70,$AE,$FB,$AD,$11,$F4,$47,$DC,$A7,$EC,$CF,$50,$C0);
  409.  
  410.   EncryptTable1:array [0..7,0..1,0..15] OF byte=  { used by encrypt3 }
  411.   {    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    }
  412.   ((( $F,$8,$5,$7,$C,$2,$E,$9,$0,$1,$6,$D,$3,$4,$B,$A),
  413.     ( $2,$C,$E,$6,$F,$0,$1,$8,$D,$3,$A,$4,$9,$B,$5,$7)),
  414.    (( $5,$2,$9,$F,$C,$4,$D,$0,$E,$A,$6,$8,$B,$1,$3,$7),
  415.     ( $F,$D,$2,$6,$7,$8,$5,$9,$0,$4,$C,$3,$1,$A,$B,$E)),
  416.    (( $5,$E,$2,$B,$D,$A,$7,$0,$8,$6,$4,$1,$F,$C,$3,$9),
  417.     ( $8,$2,$F,$A,$5,$9,$6,$C,$0,$B,$1,$D,$7,$3,$4,$E)),
  418.    (( $E,$8,$0,$9,$4,$B,$2,$7,$C,$3,$A,$5,$D,$1,$6,$F),
  419.     ( $1,$4,$8,$A,$D,$B,$7,$E,$5,$F,$3,$9,$0,$2,$6,$C)),
  420.    (( $5,$3,$C,$8,$B,$2,$E,$A,$4,$1,$D,$0,$6,$7,$F,$9),
  421.     ( $6,$0,$B,$E,$D,$4,$C,$F,$7,$2,$8,$A,$1,$5,$3,$9)),
  422.    (( $B,$5,$A,$E,$F,$1,$C,$0,$6,$4,$2,$9,$3,$D,$7,$8),
  423.     ( $7,$2,$A,$0,$E,$8,$F,$4,$C,$B,$9,$1,$5,$D,$3,$6)),
  424.    (( $7,$4,$F,$9,$5,$1,$C,$B,$0,$3,$8,$E,$2,$A,$6,$D),
  425.     ( $9,$4,$8,$0,$A,$3,$1,$C,$5,$F,$7,$2,$B,$E,$6,$D)),
  426.    (( $9,$5,$4,$7,$E,$8,$3,$1,$D,$B,$C,$2,$0,$F,$6,$A),
  427.     ( $9,$A,$B,$D,$5,$3,$F,$0,$1,$C,$8,$7,$6,$4,$E,$2))
  428.   );
  429.  
  430.  EncryptTable3:array[0..15] of byte=  { used by encrypt3 }
  431.   ( $3,$E,$F,$2,$D,$C,$4,$5,$9,$6,$0,$1,$B,$7,$A,$8 );
  432.  
  433.  
  434. PROCEDURE Shuffle(VAR ShuffleKey, buf; buflen : Word; VAR target);
  435. { UNIT INTERNAL PROCEDURE }
  436. { id, password[1.. ],length(passw), OUT: buf }
  437.  
  438.     PROCEDURE Shuffle1(VAR temp : Buf32; VAR target);
  439.     VAR _target  :  Buf16 ABSOLUTE target;
  440.         b4 :  Word;
  441.         b3 :  Byte;
  442.         d, k, i : Word;
  443.     Begin
  444.  
  445.     {** Step 4: .. }
  446.     b4 := 0;
  447.     FOR k := 0 TO 1
  448.      DO Begin
  449.         FOR i := 0 TO 31
  450.          DO Begin
  451.             b3 := Lo( Lo(temp[i] + b4) XOR
  452.                   Lo(temp[(i + b4) AND 31] - EncryptKeys[i]));
  453.             b4 := b4 + b3;
  454.             temp[i] := b3;
  455.             End;
  456.         End;
  457.  
  458.     {*** Step 5:... }
  459.  
  460.     FOR i := 0 TO 15
  461.      DO _Target[i] := EncryptTable[temp[i Shl 1]] OR
  462.                      (EncryptTable[temp[i Shl 1 +1]] Shl 4);
  463.     End;
  464.  
  465. VAR locShuffleKey : Buf4 ABSOLUTE ShuffleKey;
  466.     localBuf : ARRAY [0..127] OF Byte ABSOLUTE buf;
  467.     BufBytesUsed : Word;
  468.     temp : Buf32;
  469.     t, IndexOfBufBytes : Word;
  470. Begin
  471. { strip trailing NULLs of the to-be-encoded buf,
  472.   last element of buf must be a NULL ? }
  473. While (buflen > 0) AND (localBuf[buflen-1] = 0)
  474.  DO buflen := buflen - 1;
  475. { clear output of 1st shuffle }
  476. FillChar(temp, SizeOf(temp), #0);
  477.  
  478. {*** 1ST Step: XOR folding of first (32*(buflen DIV 32)) bytes. }
  479.  
  480. { temp= buf[0..31] XOR buf[32..63] XOR buf[64..95] XOR etc.. }
  481.  
  482. { IndexOfBufBytes is a multiple of 32, length password= IndexOfBufBytes + buflen }
  483. { Temp varuable filled with XOR folding of the first IndexOfBufBytes bytes of the PW. }
  484. IndexOfBufBytes := 0;
  485. WHILE buflen >= 32
  486.  DO Begin
  487.     FOR t := 0 TO 31
  488.      DO Begin
  489.         temp[t] := temp[t] XOR localBuf[IndexOfBufBytes];
  490.         IndexOfBufBytes := IndexOfBufBytes + 1;
  491.         End;
  492.     buflen := buflen - 32;
  493.     End;
  494.  
  495. {*** 2ND step: repetitive XOR folding with (remainder of) password
  496.  
  497.   password='hello', (BufBytesUsed=0)
  498.   or password='12345678901234567890123456789012hello' (BufBytesUsed=32)
  499.   of which the first 32 bytes were used in the 1st encryption step.
  500.  
  501.   temp=temp XOR [hellohellohellohellohellohellohe];
  502.  }
  503. BufBytesUsed:=IndexOfBufBytes;
  504. IF buflen > 0
  505.  Then Begin
  506.       FOR t := 0 TO 31
  507.        DO Begin
  508.           IF IndexOfBufBytes + buflen = BufBytesUsed
  509.            Then Begin
  510.                 BufBytesUsed := IndexOfBufBytes;
  511.                 temp[t] := temp[t] XOR EncryptKeys[t];
  512.                 End
  513.            Else Begin
  514.                 temp[t] := temp[t] XOR localBuf[BufBytesUsed];
  515.                 BufBytesUsed := BufBytesUsed + 1;
  516.                 End;
  517.           End;
  518.       End;
  519. {*** 3RD step: XOR-ing with shuffleKey (bytes of a longint)}
  520.  
  521. FOR t := 0 TO 31 DO temp[t] := temp[t] XOR locShuffleKey[t AND 3];
  522.  
  523. {*** 4&5 TH Step: see Shuffle1 }
  524.  
  525. Shuffle1(temp, target);
  526. End;
  527.  
  528. PROCEDURE Encrypt(VAR key, buf, EncrPassword);
  529. { The encryptionKey 'key' is encrypted with the aid of
  530. the shuffled login name/id within 'buf'.
  531. Result: the encrypted Password (of type TencryptionKey). }
  532. VAR _Key : TencryptionKey  ABSOLUTE Key;
  533.   _EncrKey : TencryptionKey  ABSOLUTE EncrPassword;
  534.   _LocalBuf : Buf32;
  535.   i: Byte;
  536. Begin
  537. Shuffle(_Key[0], buf, 16, _LocalBuf[0]);
  538. Shuffle(_Key[4], buf, 16, _LocalBuf[16]);
  539. FOR i := 0 TO 15 DO _LocalBuf[i] := _LocalBuf[i] XOR _LocalBuf[31-i];
  540. FOR i := 0 TO 7 DO _EncrKey[i] := _LocalBuf[i] XOR _LocalBuf[15-i];
  541. End;
  542.  
  543. Procedure EncryptPassword(objId:longint;password:string;Var Ekey:TencryptionKey);
  544. { Source of the encryption routine: LOGON.PAS by Barry Nance, [1:141/209] BYTE March'93 }
  545. { Two bugs fixed by Horst Jelonneck (930323) }
  546. Var buf:buf32;
  547.     TobjId:Longint;
  548.     Tpassword:string;
  549.  
  550. begin
  551. TobjId:=Lswap(objId);
  552. Tpassword:=password+#0;
  553. Shuffle(TObjId,Tpassword[1],length(password),buf);
  554. Encrypt(Ekey,buf,Ekey);
  555. end;
  556.  
  557. Procedure EncryptPasswordDifference(objId:Longint;
  558.                                     OldPassword,NewPassword:string;
  559.                                     Var key:TencryptionKey;
  560.                                     Var PWdif:TencrPWdifference;
  561.                                     Var PWdifChecksum:byte
  562.                                     );
  563. { Used by nwBindry.ChangeEncrBinderyObjectPassword.
  564.  
  565.   Encrypt3 and associated tables adapted from a c source (NVPW.C)
  566.   by Willem Jan Hengeveld, A.K.A. Itsme@Hacktic.nl                   }
  567.    Procedure Encrypt3(Var buf1,buf2,buf3);
  568.    { buf1: (part of) encrypted oldPW
  569.      buf2: (part of) encrypted newPW
  570.      buf3: 'change pw' data (result) }
  571.    Var p1:buf8 absolute buf1;
  572.        p2:buf8 absolute buf2;
  573.        p3:buf8 absolute buf3;
  574.        j,c,i:byte;
  575.        buf:buf8;
  576.    begin
  577.    buf:=p2;
  578.    for i:=0 to 15
  579.     do begin
  580.  
  581.        for j:=0 to 7
  582.         do begin
  583.            c:=buf[j] XOR p1[j];
  584.            buf[j]:=EncryptTable1[j][0][c AND $0F]
  585.                    OR (EncryptTable1[j][1][c SHR 4] SHL 4);
  586.            end;
  587.  
  588.        c:=p1[7];
  589.        for j:=7 downto 1
  590.         do p1[j]:=(p1[j] SHL 4) OR (p1[j-1] SHR 4);
  591.        p1[0]:=(c SHR 4) OR (p1[0] SHL 4);
  592.  
  593.        FillChar(p3,8,#$0);
  594.        for j:=0 to 15
  595.         do begin
  596.            c:=EncryptTable3[j];
  597.            If odd(EncryptTable3[j])
  598.             then c:=buf[c DIV 2] SHR 4
  599.             else c:=buf[c DIV 2] AND $0F;
  600.            if Odd(j)
  601.             then p3[j DIV 2]:=p3[j DIV 2] XOR (c SHL 4)
  602.             else p3[j DIV 2]:=p3[j DIV 2] XOR c;
  603.            end;
  604.  
  605.        buf:=p3;
  606.        end;
  607.    end;
  608. Var l:byte;
  609.     OldShuffledPW,NewShuffledPW:array[0..15] of byte;
  610. begin
  611. objId:=Lswap(objId);
  612. Shuffle(objId,OldPassword[1],Length(OldPassword),OldShuffledPW);
  613. Shuffle(objId,NewPassword[1],Length(NewPassword),NewShuffledPW);
  614. Encrypt(key,OldShuffledPW,key);
  615.  
  616. Encrypt3(OldShuffledPW,NewShuffledPW,PWdif);
  617. Encrypt3(OldShuffledPW[8],NewShuffledPW[8],PWdif[8]);
  618. if Length(NewPassword)<63
  619.  then l:=length(NewPassword)
  620.  else l:=63;
  621. PWdifChecksum:=(((l XOR OldShuffledPW[1] XOR OldShuffledPW[2]) AND $7F) OR $40);
  622. end;
  623.  
  624.  
  625. {-------------- End of encryption procedures ----------------------------}
  626.  
  627. Procedure UpString(s : String); Assembler;
  628. { fast upcasestring by Bob Swart }
  629. ASM
  630.         PUSH   DS
  631.         LDS    SI, s
  632.         LES    DI, s
  633.         CLD
  634.         XOR    AH, AH
  635.         LODSB
  636.         STOSB
  637.         XCHG   AX, CX           { empty string? }
  638.         JCXZ   @2
  639. @1:     LODSB
  640.         SUB    AL, 'a'
  641.         CMP    AL, 'z'-'a'+1
  642.         SBB    AH, AH
  643.         AND    AH, 'a'-'A'
  644.         SUB    AL, AH
  645.         ADD    AL, 'a'
  646.         STOSB
  647.         LOOP   @1
  648. @2:     POP    DS
  649. end;
  650.  
  651.  
  652. procedure ZStrCopy(dest:String;Var source;len:byte); assembler;
  653. { 1. Copies len bytes from an array to a pascal type string.                }
  654. { 2. Trailing NULLs are removed from the string.                            }
  655. { consequently, the length of det (dest[0]) will allways be <= len.         }
  656. asm
  657.       mov dx,ds
  658.  
  659.       les di,dest
  660.       xor ch,ch
  661.       mov [es:di],ch  { dest[0]:=#0 }
  662.       mov cl,len
  663.       jcxz @4         { if len=0 then goto @4 }
  664.       lds si,source
  665. @3:   lodsb
  666.       or al,al
  667.       jz @2           { determine non-0 length of source }
  668.       dec cx
  669.       jnz @3
  670. @2:   xor ax,ax
  671.       mov al,len
  672.       sub ax,cx       { ax:= bytes to copy }
  673.  
  674.       les di,dest
  675.       lds si,source
  676.       mov es:[di],al  { dest[0]:=actual non-0 len }
  677.       inc di          { es:di => dest[1] ; ds:si => source[0] }
  678.  
  679.       mov cx,ax
  680.       cld
  681.       rep movsb       { copy cx bytes from ds:si to es:di }
  682.  
  683. @4:   mov ds,dx
  684. end;
  685.  
  686. procedure PStrCopy(Var dest:String;source:String;len:byte);
  687. Var w:byte;
  688. begin
  689. w:=1;
  690. dest[0]:=chr(len);
  691. While w<=ord(source[0])
  692.  do begin
  693.     dest[w]:=source[w];
  694.     inc(w)
  695.     end;
  696. While w<=len
  697.  do begin
  698.     dest[w]:=#0;
  699.     inc(w)
  700.     end;
  701. end;
  702.  
  703. Procedure NovTime2String(tim:TnovTime;Var DateStr:string);
  704. CONST day:array[0..6] of string[3]
  705.           =('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  706.       Month:array[1..12] of string[3]
  707.           =('Jan','Feb','Mar','Apr','May','Jun',
  708.             'Jul','Aug','Sep','Oct','Nov','Dec');
  709. Type string4=string[4];
  710. Var  sday,syear,shour,smin,ssec:string4;
  711.   Procedure zstr(n:byte;Var s:string4);
  712.   begin
  713.   str(n,s);
  714.   if s[0]=#1 then s:='0'+s;
  715.   end;
  716. begin
  717. if (tim.month>12) or (tim.month<1)
  718.    or (tim.day<1) or (tim.day>31)
  719.    or (tim.hour>23) or (tim.min>59) or (tim.sec>59)
  720.  then DateStr:='<invalid date & time>    '
  721.  else begin
  722.       zstr(tim.day,sday);
  723.       if sday[1]='0' then sday[1]:=' ';
  724.       if tim.year<80 then str(tim.year+2000,syear)
  725.                      else str(tim.year+1900,syear);
  726.       zstr(tim.hour,shour);
  727.       zstr(tim.min,smin);
  728.       zstr(tim.sec,ssec);
  729.       DateStr:=day[tim.DayOfWeek]+', '+
  730.                sday+' '+Month[tim.month]+' '+syear+' '+
  731.                shour+':'+smin+':'+ssec;
  732.       end;
  733. end;
  734.  
  735. Procedure DosTime2NovTime(dt:Longint;Var nt:TnovTime);
  736. Var k:array[1..2] of word absolute dt;
  737. begin
  738. with nt
  739.  do begin
  740.     year:=(80+byte(k[2] SHR 9)) MOD 100;
  741.     month:=(byte(k[2] SHR 5) AND 15);
  742.     day:=byte(k[2] AND 31);
  743.  
  744.     hour:=byte (k[1] SHR 11);
  745.     min:=(byte(k[1] SHR 5) AND 63);
  746.     sec:=2*byte(k[1] AND 31);
  747.     end;
  748. end;
  749.  
  750.  
  751. Procedure NovTime2DosTime(nt:TnovTime;Var dt:Longint);
  752. Var k:array[1..2] of word absolute dt;
  753. begin
  754. with nt
  755.  do begin
  756.     k[2]:=(((100+year-80) mod 100) SHL 9)+(month SHL 5)+day;
  757.     k[1]:=(hour SHL 11)+(min SHL 5)+(sec DIV 2);
  758.     end;
  759. end;
  760.  
  761. Procedure NovPath2DosPath(np:String;Var dp:string);
  762. { np is a pascal type string with the folowing format:
  763.  
  764.   chr(length(subdir1)),subdir1,
  765.   ...
  766.   chr(length(subdirN)),subDirN.
  767.  
  768.   It will be transformed to a DOS path of type Subdir1\Subdir2\.. \subDirN }
  769. Var t:Byte;
  770. begin
  771. dp:=np;
  772. delete(dp,1,1);
  773. for t:=1 to ord(dp[1])
  774.  do if dp[t]<=#20 then dp[t]:='\';
  775. end;
  776.  
  777.  
  778. Function LoNibble(b:Byte):Byte; assembler;
  779. asm
  780. mov al,b
  781. and al,$0F
  782. end;
  783.  
  784. Function HiNibble(b:Byte):Byte; assembler;
  785. asm
  786. mov ah,$00
  787. mov al,b
  788. shr ax,1
  789. shr ax,1
  790. shr ax,1
  791. shr ax,1
  792. end;
  793.  
  794. Function HexStr(dw:LongInt;len:byte):string;
  795. CONST n:array[0..15] of char
  796.       =('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
  797. Var t:integer;
  798.     ldw:LongInt;
  799.     res:string;
  800. begin
  801. res:='';
  802. for t:=1 to len
  803. do begin
  804.    ldw:=dw AND $0000000F;
  805.    res:=n[ldw]+res;
  806.    dw:=dw SHR 4;
  807.    end;
  808. HexStr:=res;
  809. end;
  810.  
  811. Function HexDumpStr(Var dumpVar;len:Byte):String;
  812. Var arr:Array[1..256] of Byte ABSOLUTE dumpVar;
  813.     t:Byte;
  814.     res:String;
  815. begin
  816. res:='';
  817. for t:=1 to (1+(len DIV 2))
  818.  do res:=res+HexStr(arr[t],2);
  819. res[0]:=chr(len);
  820. HexDumpStr:=res;
  821. end;
  822.  
  823. Function IsLowerNetworkAddress(Var a, b): Boolean;
  824. Type TCharNetAddress = Array [1..10] of Char;
  825. Var Aaddr : TCharNetAddress ABSOLUTE a;
  826.     Baddr : TCharNetAddress ABSOLUTE b;
  827. Begin
  828.     IsLowerNetworkAddress := Aaddr < Baddr;
  829. End;
  830.  
  831. Function IsEqualNetworkAddress(Var a, b): Boolean;
  832. Type TCharNetAddress = Array [1..10] of Char;
  833. Var Aaddr : TCharNetAddress ABSOLUTE a;
  834.     Baddr : TCharNetAddress ABSOLUTE b;
  835. Begin
  836.     IsEqualNetworkAddress := (Aaddr = Baddr);
  837. End;
  838.  
  839. Function IsLaterNovTime(time1,time2:TnovTime):boolean;
  840. Var bAft:boolean;
  841.     y1,y2:word;
  842. begin
  843. if time1.year>=80
  844.  then y1:=1900+time1.year
  845.  else y1:=2000+time1.year;
  846. if time2.year>=80
  847.  then y2:=1900+time2.year
  848.  else y2:=2000+time2.year;
  849. bAft:=(y1>y2);
  850. if y1=y2
  851.  then begin
  852.       bAft:=(time1.month>time2.month);
  853.       if time1.month=time2.month
  854.        then begin
  855.             bAft:=(time1.day>time2.day);
  856.             if time1.day=time2.day
  857.              then begin
  858.                   bAft:=(time1.hour>time2.hour);
  859.                   if time1.hour=time2.hour
  860.                    then begin
  861.                         bAft:=(time1.min>time2.min);
  862.                         if time1.min=time2.min
  863.                          then bAft:=(time1.sec>time2.sec);
  864.                         end;
  865.                   end;
  866.             end;
  867.       end;
  868. IsLaterNovTime:=bAft
  869. end;
  870.  
  871.  
  872. Function IsEqualNovTime(time1,time2:TnovTime):boolean;
  873. Var t1:array[1..Sizeof(TnovTime)-1] of char absolute time1;
  874.     t2:array[1..SizeOf(TnovTime)-1] of char absolute time2;
  875. begin
  876. IsEqualNovTime:=(t1=t2);
  877. end;
  878.  
  879.  
  880. Function MapV2RightsToV3(V2Rights:byte):word;
  881. CONST RightsNotChanged:byte=$08+$10+$40+$80;
  882. Var result:Word;
  883. begin
  884. if (V2Rights and $FF)>0
  885.  then result:=$1FF
  886.  else begin
  887.       result:=(V2Rights and RightsNotChanged);
  888.       if (V2Rights and ($01+$04))>0
  889.        then result:=result or $01;
  890.       if (V2Rights and ($02+$04))>0
  891.        then result:=result or $02;
  892.       if (V2Rights and $04)>0
  893.        then result:=result or $01;
  894.       if (V2Rights and $20)>0
  895.        then result:=result or $28;
  896.       end;
  897. MapV2RightsToV3:=result;
  898. end;
  899.  
  900. Function MapV3RightsToV2(V3Rights:Word):Byte;
  901. CONST RightsNotChanged:word=$10+$20+$40+$80;
  902. Var result:Byte;
  903. begin
  904. If (V3Rights and $0100)>0
  905.  then result:=$FF
  906.  else begin
  907.       result:=(lo(V3Rights) and RightsNotChanged);
  908.       If (V3Rights and $01)>0
  909.        then result:=result or $05;
  910.       If (V3Rights and $02)>0
  911.        then result:=result or $06;
  912.      {If (V3Rights and $04)>0
  913.        then result:=result or $00;}
  914.       If (V3Rights and $08)>0
  915.        then result:=result or $28;
  916.       end;
  917. MapV3RightsToV2:=result;
  918. end;
  919.  
  920. Procedure GetNWversion(Var version:word);
  921. { determine the version of the software installed on the current file server. }
  922. { see GetFileServerInformation F217/11 in the nwServ unit for more information }
  923.  
  924. { version : word; contains the versionnumber of the fileserver we're
  925.             currently connected to. Used by primary functions to
  926.             determine what type of calls to use to perform a certain function.
  927.  
  928.             format: (majorVersion*100)+minorVersion
  929.                     e.g. 311 for 3.11
  930.             Range: 215 (advanced netware 2.15) and upwards    }
  931. { If the version is lower than 2.15, 2.15 is returned.        }
  932. { note: you don't have to be logged in to call this function. }
  933. Type TReq= Record
  934.            PacketLength : Word;
  935.            FunctionVal  : Byte;
  936.            End;
  937.      TRep=array[1..$80] of byte;
  938.      Tpreq=^Treq;
  939.      Tprep=^Trep;
  940. Var Result:word;
  941. Begin
  942. With TPreq(GlobalReqBuf)^
  943. Do Begin
  944.    PacketLength := 1; FunctionVal := $11;
  945.    End;
  946. F2SystemCall($17,sizeof(Treq),Sizeof(Trep),result);
  947. If result=0
  948.  then version:=(TPrep(GlobalReplyBuf)^[49]*100)+TPrep(GlobalReplyBuf)^[50]
  949.  else version:=215;
  950. End;
  951.  
  952.  
  953. Function IsV3Supported:boolean;
  954. Var version:word;
  955. begin
  956. GetNWversion(version);
  957. IsV3Supported:=(version>=300);
  958. end;
  959.  
  960.  
  961. END.
  962.